import torch
from utils.util import LD_param as get_res
from utils.util import AverageMeter,save_csv,mergetotxt,SSIM,PSNR,normal
import os
import torch.nn as nn
import numpy as np
from  numpy.fft import fft2,fftshift

def change_fre(F):
        ans = 100 - F
        if ans <= 0:
            ans = 0
        return ans
    
def get_frequency(src):
        res = []
        for i in range(src.shape[0]):
            res.append(fftshift(fft2(src[i,:,:])))
        return torch.tensor(np.array(res))
    
class NewAverageMeter(AverageMeter):
    def __init__(self):
        AverageMeter.__init__(self)
        # self.reset()

    def reset(self):
        # self.val = 0
        # self.avg = 0
        # self.sum = 0
        # self.count = 0
        AverageMeter.reset(self)
        self.fea = []
        # self.fea_dict = [{}]

    def update(self, val, n=1,paths = None):
        if paths == None:
            paths = ['']*n
        # for i in range(n):
        #     tmp = {}
        #     tmp['value'] = val
        #     tmp['path'] = path[i]
        tmp = [val] * n
        self.fea+=list(zip(tmp,paths))
        
        AverageMeter.update(self,val,n)
            
        # self.val = val
        # self.sum += val * n
        # self.count += n
        # self.avg = self.sum / self.count
    
    # tmp = int(self.count*0.1)
    # self.avg10p = sum(self.fea)

    def update_np(self,vals,paths=None):
        # self.sum = np.sum(val,0)
        # self.count += val.shape[0]
        # self.avg = self.sum / self.count\
        if paths == None:
            paths = [''] * vals.shape[0]
            paths = np.array(paths)
        # for (val,path) in zip(vals,paths):
        #     tmp = {}
        #     tmp['value'] = val
        #     tmp['path'] = path
        self.fea += list(zip(vals,paths))
        AverageMeter.update_np(self,vals)
    
    def statistic(self):
        self.fea.sort(key=lambda x:x[0])
        _len = len(self.fea)
        if _len >= 10 :
            self.Min10p = sum([x[0] for x in self.fea[:int(_len*0.1)]])/int(_len*0.1)
        else:
            self.Min10p = self.avg
            
        if _len >= 2:
            self.Min50p = sum([x[0] for x in self.fea[:int(_len*0.5)]])/int(_len*0.5)
        else:
            self.Min50p = self.avg
        
        self.fea.reverse()
        if _len >= 10 :
            self.Top10p = sum([x[0] for x in self.fea[:int(_len*0.1)]])/int(_len*0.1)
        else:
            self.Top10p = self.avg
        if _len >= 2:
            self.Top50p = sum([x[0] for x in self.fea[:int(_len*0.5)]])/int(_len*0.5)
        else:
            self.Top50p = self.avg
    def saveTop10p(self,savedir,filename):
        path = os.path.join(savedir,filename)
        _len = int(len(self.fea) * 0.1)
        with open(path,'w')as f:
            f.write('Top10p: {} Top50p:{} Top100p:{}\n'.format(self.Top10p,self.Top50p,self.avg))
            for i in range(_len):
                tmp = self.fea[i][1].__str__()
                f.write(tmp+'\n')

class TestApi():
    def __init__(self,opt):
        self.D_generation = opt.D_generation
        self.frequency = opt.frequency
        self.batch_size = opt.batch_size
        self.use_inception = opt.use_inception
        self.loss = nn.MSELoss()
        self.controller = opt.controller
        self.name = opt.name
        self.version = opt.version
        self.phase = opt.phase
        self.epoch = opt.epoch
        self.c = 1e-10
        pass
    def init(self,mode):
        self.mode = mode

        # self.Fmode = Fmode
        if mode:
            self.count_mean_G=AverageMeter()
            self.count_mean_G_S10=AverageMeter()
            self.count_mean_G_S01=AverageMeter()
            self.count_mean_G_S20=AverageMeter()
            self.count_mean_G_S02=AverageMeter()
            self.count_mean_G_SD0=AverageMeter()
            self.count_mean_G_S0D=AverageMeter()
            self.count_mean_D_S0 = AverageMeter()
            self.count_mean_D_S1 = AverageMeter()
            self.count_mean_D_S2 = AverageMeter()
            self.count_mean_D_SD = AverageMeter()
        else:
            self.count_mean_S01_PSNR=AverageMeter()
            self.count_mean_S02_PSNR=AverageMeter()
            self.count_mean_PSNR_S1=AverageMeter()
            self.count_mean_PSNR_S2=AverageMeter()
            self.count_mean_S0D_PSNR=AverageMeter()
            
            # style
            self.count_mean_SSIM_S1=NewAverageMeter()
            self.count_mean_SSIM_S2=NewAverageMeter()
            self.count_mean_S01_SSIM=AverageMeter()
            self.count_mean_S02_SSIM=AverageMeter()
            self.count_mean_S0D_SSIM=AverageMeter()
            
            if self.use_inception:
                self.features = {}
                self.features['real_S1'] = []
                self.features['real_S2'] = []
                self.features['real_SD'] = []
                self.features['fake_S1'] = []
                self.features['fake_S2'] = []
                self.features['fake_SD'] = []
                self.count_mean_FID_S1=NewAverageMeter()
                self.count_mean_FID_S2=NewAverageMeter()
                self.count_mean_FID_S01=AverageMeter()
                self.count_mean_FID_S02=AverageMeter()
                self.count_mean_FID_S0D=AverageMeter()
                self.count_mean_S1disFID=NewAverageMeter()
                self.count_mean_S2disFID=NewAverageMeter()
                self.count_mean_SDdisFID=NewAverageMeter()
                
            if self.D_generation == "source":
                self.count_mean_SSIM_SD=NewAverageMeter()
                self.count_mean_PSNR_SD=AverageMeter()
                if self.use_inception:
                    self.count_mean_FID_SD=NewAverageMeter()
            elif self.D_generation == "mergeS12":
                self.count_mean_SSIM_S12D=AverageMeter()
                self.count_mean_PSNR_S12D=AverageMeter()

        if self.frequency:
            self.count_mean_F_S1=NewAverageMeter()
            self.count_mean_F_S01=AverageMeter()
            self.count_mean_F_S2=NewAverageMeter()
            self.count_mean_F_S02=AverageMeter()
            self.count_mean_F_SD=NewAverageMeter()
            self.count_mean_F_S0D=AverageMeter()
            self.count_mean_F_S12D=AverageMeter()
            
            self.count_mean_DF_S1=NewAverageMeter()
            self.count_mean_DF_S2=NewAverageMeter()
            self.count_mean_DF_SD=NewAverageMeter()
            
    def record(self,records):
        out = {}
        if self.mode:
            self.count_mean_G.update(records['loss_G'].contiguous().detach().cpu(),self.batch_size)
            self.count_mean_G_S01.update(records['loss_G_S01'].contiguous().detach().cpu(),self.batch_size)
            self.count_mean_G_S10.update(records['loss_G_S10'].contiguous().detach().cpu(),self.batch_size)
            self.count_mean_G_S02.update(records['loss_G_S02'].contiguous().detach().cpu(),self.batch_size)
            self.count_mean_G_S20.update(records['loss_G_S20'].contiguous().detach().cpu(),self.batch_size)
            self.count_mean_G_S0D.update(records['loss_G_S0D'].contiguous().detach().cpu(),self.batch_size)
            self.count_mean_G_SD0.update(records['loss_G_SD0'].contiguous().detach().cpu(),self.batch_size)
            
            self.count_mean_D_S0.update(records["loss_D_S0"])
            self.count_mean_D_S1.update(records["loss_D_S1"])
            self.count_mean_D_S2.update(records["loss_D_S2"])
            self.count_mean_D_SD.update(records["loss_D_SD"])
            
            out["count_mean_G"]=self.count_mean_G.avg
            out["count_mean_G_S01"]=self.count_mean_G_S01.avg
            out["count_mean_G_S10"]=self.count_mean_G_S10.avg
            out["count_mean_G_S02"]=self.count_mean_G_S02.avg
            out["count_mean_G_S20"]=self.count_mean_G_S20.avg
            out["count_mean_G_S0D"]=self.count_mean_G_S0D.avg
            out["count_mean_G_SD0"]=self.count_mean_G_SD0.avg
            
            out["count_mean_D_S0"]=self.count_mean_D_S0.avg
            out["count_mean_D_S1"]=self.count_mean_D_S1.avg
            out["count_mean_D_S2"]=self.count_mean_D_S2.avg
            out["count_mean_D_SD"]=self.count_mean_D_SD.avg
            
        else:
            
            if self.D_generation == "source":
                loss_PSNR_SD = PSNR(records['fake_S0D']["generation"],records['real_SD'])
                loss_SSIM_SD = SSIM(records['fake_S0D']["generation"],records['real_SD'])
                self.count_mean_PSNR_SD.update(loss_PSNR_SD,self.batch_size)
                self.count_mean_SSIM_SD.update(loss_SSIM_SD,self.batch_size,records["image_paths"])
                # self.loss_mean_SSIM_SD = self.count_mean_SSIM_SD.avg
                out["count_mean_PSNR_SD"] = self.count_mean_PSNR_SD.avg
                out["count_mean_SSIM_SD"] = self.count_mean_SSIM_SD.avg                  
            elif self.D_generation == "mergeS12":
                loss_PSNR_S12D = PSNR(records['fake_S12D'],records['real_SD'])
                self.count_mean_PSNR_S12D.update(loss_PSNR_S12D,self.batch_size)
                # self.loss_mean_PSNR_S12D = self.count_mean_PSNR_S12D.avg
                
                loss_SSIM_S12D = SSIM(records['fake_S12D'],records['real_SD'])
                self.count_mean_SSIM_S12D.update(loss_SSIM_S12D,self.batch_size)
                # self.loss_mean_SSIM_S12D = self.count_mean_SSIM_S12D.avg  
                out["count_mean_PSNR_S12D"] = self.count_mean_PSNR_S12D.avg
                out["count_mean_SSIM_S12D"] = self.count_mean_SSIM_S12D.avg
                
            loss_PSNR_S1 = PSNR(records['fake_S01'],records['real_S1'])
            loss_PSNR_S2 = PSNR(records['fake_S02'],records['real_S2'])
            loss_S01_PSNR = PSNR(records['real_S0'],records['real_S1'])
            loss_S02_PSNR = PSNR(records['real_S0'],records['real_S2'])
            loss_S0D_PSNR = PSNR(records['real_S0'],records['real_SD'])
            
            loss_SSIM_S1 = SSIM(records['fake_S01'],records['real_S1'])
            loss_SSIM_S2 = SSIM(records['fake_S02'],records['real_S2'])
            loss_S01_SSIM = SSIM(records['real_S0'],records['real_S1'])
            loss_S02_SSIM = SSIM(records['real_S0'],records['real_S2'])
            loss_S0D_SSIM = SSIM(records['real_S0'],records['real_SD'])
            
            self.count_mean_PSNR_S1.update(loss_PSNR_S1,self.batch_size)
            self.count_mean_PSNR_S2.update(loss_PSNR_S2,self.batch_size)
            self.count_mean_S01_PSNR.update(loss_S01_PSNR,self.batch_size)
            self.count_mean_S02_PSNR.update(loss_S02_PSNR,self.batch_size)
            self.count_mean_S0D_PSNR.update(loss_S0D_PSNR,self.batch_size)
            
            self.count_mean_SSIM_S1.update(loss_SSIM_S1,self.batch_size,records["image_paths"])
            self.count_mean_SSIM_S2.update(loss_SSIM_S2,self.batch_size,records["image_paths"])
            self.count_mean_S01_SSIM.update(loss_S01_SSIM,self.batch_size)
            self.count_mean_S02_SSIM.update(loss_S02_SSIM,self.batch_size)
            self.count_mean_S0D_SSIM.update(loss_S0D_SSIM,self.batch_size)
            
            out["count_mean_PSNR_S1"] = self.count_mean_PSNR_S1.avg
            out["count_mean_PSNR_S2"] = self.count_mean_PSNR_S2.avg
            out["count_mean_S01_PSNR"] = self.count_mean_S01_PSNR.avg
            out["count_mean_S02_PSNR"] = self.count_mean_S02_PSNR.avg
            out["count_mean_S0D_PSNR"] = self.count_mean_S0D_PSNR.avg
            out["count_mean_SSIM_S1"] = self.count_mean_SSIM_S1.avg
            out["count_mean_SSIM_S2"] = self.count_mean_SSIM_S2.avg
            out["count_mean_S01_SSIM"] = self.count_mean_S01_SSIM.avg
            out["count_mean_S02_SSIM"] = self.count_mean_S02_SSIM.avg
            out["count_mean_S0D_SSIM"] = self.count_mean_S0D_SSIM.avg
            if self.use_inception:
                
                # self.features['real_S1'].append(records['real_S1']['feature'].squeeze(0).squeeze(0).flatten().contiguous().cpu().detach().numpy())
                # self.features['real_S2'].append(records['real_S2']['feature'].squeeze(0).squeeze(0).flatten().contiguous().cpu().detach().numpy())
                # self.features['real_SD'].append(records['real_SD']['feature'].squeeze(0).squeeze(0).flatten().contiguous().cpu().detach().numpy())
                # self.features['fake_S1'].append(records['fake_S1']['feature'].squeeze(0).squeeze(0).flatten().contiguous().cpu().detach().numpy())
                # self.features['fake_S2'].append(records['fake_S2']['feature'].squeeze(0).squeeze(0).flatten().contiguous().cpu().detach().numpy())
                # self.features['fake_SD'].append(records['fake_SD']['feature'].squeeze(0).squeeze(0).flatten().contiguous().cpu().detach().numpy())
                
                # loss_FID_S1 = self.loss(records['real_S1']['feature'],records['fake_S1']['feature'])
                # loss_FID_S2 = self.loss(records['real_S2']['feature'],records['fake_S2']['feature'])
                # loss_FID_SD = self.loss(records['real_SD']['feature'],records['fake_SD']['feature'])
                # loss_FID_S01 = self.loss(records['fake_S01']['feature'],records['idt_S01']['feature'])
                # loss_FID_S02 = self.loss(records['real_S0']['feature'],records['real_S2']['feature'])
                # loss_FID_S0D = self.loss(records['real_S0']['feature'],records['real_SD']['feature'])
                
                loss_DISFID_S1 = records['loss_FID_S1']/(records["loss_FID_S01"]+self.c)
                loss_DISFID_S2 = records['loss_FID_S2']/(records["loss_FID_S02"]+self.c)
                loss_DISFID_SD = records['loss_FID_SD']/(records["loss_FID_S0D"]+self.c)
                

                self.count_mean_FID_S1.update(records['loss_FID_S1'],self.batch_size,records["image_paths"])
                self.count_mean_FID_S2.update(records['loss_FID_S2'],self.batch_size,records["image_paths"])
                self.count_mean_FID_S01.update(records["loss_FID_S01"],self.batch_size)
                self.count_mean_FID_S02.update(records["loss_FID_S02"],self.batch_size)
                self.count_mean_FID_S0D.update(records["loss_FID_S0D"],self.batch_size)
                self.count_mean_FID_SD.update(records['loss_FID_SD'],self.batch_size,records["image_paths"])
                
                self.count_mean_S1disFID.update(loss_DISFID_S1,self.batch_size,records["image_paths"])
                self.count_mean_S2disFID.update(loss_DISFID_S2,self.batch_size,records["image_paths"])
                self.count_mean_SDdisFID.update(loss_DISFID_SD,self.batch_size,records["image_paths"])
                
                
                out["count_mean_FID_S1"] = self.count_mean_FID_S1.avg
                out["count_mean_FID_S2"] = self.count_mean_FID_S2.avg
                out["count_mean_FID_SD"] = self.count_mean_FID_SD.avg
                out["count_mean_FID_S01"] = self.count_mean_FID_S01.avg
                out["count_mean_FID_S02"] = self.count_mean_FID_S02.avg
                out["count_mean_FID_S0D"] = self.count_mean_FID_S0D.avg
                out["count_mean_S1disFID"] = self.count_mean_S1disFID.avg
                out["count_mean_S2disFID"] = self.count_mean_S2disFID.avg
                out["count_mean_SDdisFID"] = self.count_mean_SDdisFID.avg
                
        if self.frequency:
            if self.D_generation == "source":
                self.count_mean_F_SD.update(records["loss_F_SD"].contiguous().detach().cpu(),self.batch_size,records["image_paths"])
                self.count_mean_F_S0D.update(records["loss_F_S0D"].contiguous().detach().cpu(),self.batch_size)
                self.count_mean_DF_SD.update(records["loss_F_SD"].contiguous().detach().cpu()/(records["loss_F_S0D"].contiguous().detach().cpu()+self.c),self.batch_size,records["image_paths"])
                out["count_mean_F_SD"] = change_fre(self.count_mean_F_SD.avg)
                out["count_mean_F_S0D"] = change_fre(self.count_mean_F_S0D.avg)
            elif self.D_generation == "mergeS12":
                self.count_mean_F_S12D.update(records["loss_F_S12D"].contiguous().detach().cpu(),self.batch_size)

                out["count_mean_F_S12D"] = change_fre(self.count_mean_F_S12D.avg)
            
            self.count_mean_F_S1.update(records["loss_F_S1"].contiguous().detach().cpu(),self.batch_size,records["image_paths"])
            self.count_mean_F_S01.update(records["loss_F_S01"].contiguous().detach().cpu(),self.batch_size)
            self.count_mean_F_S2.update(records["loss_F_S2"].contiguous().detach().cpu(),self.batch_size,records["image_paths"])
            self.count_mean_F_S02.update(records["loss_F_S02"].contiguous().detach().cpu(),self.batch_size)
            self.count_mean_DF_S1.update(records["loss_F_S1"].contiguous().detach().cpu()/(records["loss_F_S01"].contiguous().detach().cpu()+self.c),self.batch_size,records["image_paths"])
            self.count_mean_DF_S2.update(records["loss_F_S2"].contiguous().detach().cpu()/(records["loss_F_S02"].contiguous().detach().cpu()+self.c),self.batch_size,records["image_paths"])

            out["count_mean_F_S1"] = change_fre(self.count_mean_F_S1.avg)
            out["count_mean_F_S01"] = change_fre(self.count_mean_F_S01.avg)
            out["count_mean_F_S2"] = change_fre(self.count_mean_F_S2.avg)
            out["count_mean_F_S02"] = change_fre(self.count_mean_F_S02.avg)
        return out
    
    def statistic(self):
        res = {}
        if self.mode:
            self.count_mean_G.reset()
            self.count_mean_G_S10.reset()
            self.count_mean_G_S01.reset()
            self.count_mean_G_S20.reset()
            self.count_mean_G_S02.reset()
            self.count_mean_G_SD0.reset()
            self.count_mean_G_S0D.reset()
            self.count_mean_D_S0.reset()
            self.count_mean_D_S1.reset()
            self.count_mean_D_S2.reset()
            self.count_mean_D_SD.reset()
        else:
            # self.count_mean_S012D_SSIM.statistic()
            self.count_mean_SSIM_S1.statistic()
            self.count_mean_SSIM_S2.statistic()
            self.count_mean_SSIM_SD.statistic()
            if self.use_inception:
                # self.features = np.array(self.features)
                # pairs = [('real_S1','fake_S1'),('real_S2','fake_S2'),('real_SD','fake_SD')]
                # var = np.var(self.features,axis=0)
                # x,y = self.features[:,np.argsort(var)[-1]],self.features[:,np.argsort(var)[-2]]
                # for pair in pairs:
                #     draw_Fea(np.array(self.features[pair[0]]),np.array(self.features[pair[1]]),pair[0].split('_')[1],os.path.join(os.path.abspath('.'),'results',self.name+'_v'+self.version,self.phase+'_'+self.epoch,pair[0].split('_')[1]+'_last2feamap.png'))
                
                
                self.count_mean_FID_S1.statistic()
                self.count_mean_FID_S2.statistic()
                self.count_mean_FID_SD.statistic()
                self.count_mean_S1disFID.statistic()
                self.count_mean_S2disFID.statistic()
                self.count_mean_SDdisFID.statistic()
                
            if self.controller == 'test':
                # self.count_mean_S012D_SSIM.saveTop10p(os.path.join(os.path.abspath('.'),'results',self.name+'_v'+self.version,self.phase+'_'+self.epoch),'Top10pImgPaths.txt')
                # self.loss_mean_F_S1 = change_fre(self.loss_mean_F_S1)
                # self.loss_mean_F_S2 = change_fre(self.loss_mean_F_S2)
                # self.loss_mean_F_SD = change_fre(self.loss_mean_F_SD)
                if self.frequency:
                    self.count_mean_F_S1.statistic()
                    self.count_mean_F_S2.statistic()
                    self.count_mean_F_SD.statistic()
                    self.count_mean_DF_S1.statistic()
                    self.count_mean_DF_S2.statistic()
                    self.count_mean_DF_SD.statistic()
                    self.count_mean_DF_S1.saveTop10p(os.path.join(os.path.abspath('.'),'results',self.name+'_v'+self.version,self.phase+'_'+self.epoch),'DFre_S1.txt')
                    self.count_mean_DF_S2.saveTop10p(os.path.join(os.path.abspath('.'),'results',self.name+'_v'+self.version,self.phase+'_'+self.epoch),'DFre_S2.txt')
                    self.count_mean_DF_SD.saveTop10p(os.path.join(os.path.abspath('.'),'results',self.name+'_v'+self.version,self.phase+'_'+self.epoch),'DFre_SD.txt')
                    self.count_mean_F_S1.saveTop10p(os.path.join(os.path.abspath('.'),'results',self.name+'_v'+self.version,self.phase+'_'+self.epoch),'Fre_S1.txt')
                    self.count_mean_F_S2.saveTop10p(os.path.join(os.path.abspath('.'),'results',self.name+'_v'+self.version,self.phase+'_'+self.epoch),'Fre_S2.txt')
                    self.count_mean_F_SD.saveTop10p(os.path.join(os.path.abspath('.'),'results',self.name+'_v'+self.version,self.phase+'_'+self.epoch),'Fre_SD.txt')
                    
                self.count_mean_SSIM_S1.saveTop10p(os.path.join(os.path.abspath('.'),'results',self.name+'_v'+self.version,self.phase+'_'+self.epoch),'Top100pImgPaths_S1.txt')
                self.count_mean_SSIM_S2.saveTop10p(os.path.join(os.path.abspath('.'),'results',self.name+'_v'+self.version,self.phase+'_'+self.epoch),'Top100pImgPaths_S2.txt')
                self.count_mean_SSIM_SD.saveTop10p(os.path.join(os.path.abspath('.'),'results',self.name+'_v'+self.version,self.phase+'_'+self.epoch),'Top100pImgPaths_SD.txt')
                
                if self.use_inception:
                    self.count_mean_FID_S1.saveTop10p(os.path.join(os.path.abspath('.'),'results',self.name+'_v'+self.version,self.phase+'_'+self.epoch),'FID_S1.txt')
                    self.count_mean_FID_S2.saveTop10p(os.path.join(os.path.abspath('.'),'results',self.name+'_v'+self.version,self.phase+'_'+self.epoch),'FID_S2.txt')
                    self.count_mean_FID_SD.saveTop10p(os.path.join(os.path.abspath('.'),'results',self.name+'_v'+self.version,self.phase+'_'+self.epoch),'FID_SD.txt')
                    self.count_mean_S1disFID.saveTop10p(os.path.join(os.path.abspath('.'),'results',self.name+'_v'+self.version,self.phase+'_'+self.epoch),'DFID_S1.txt')
                    self.count_mean_S2disFID.saveTop10p(os.path.join(os.path.abspath('.'),'results',self.name+'_v'+self.version,self.phase+'_'+self.epoch),'DFID_S2.txt')
                    self.count_mean_SDdisFID.saveTop10p(os.path.join(os.path.abspath('.'),'results',self.name+'_v'+self.version,self.phase+'_'+self.epoch),'DFID_SD.txt')

                    
                

                pass
            # self.TOP10p_mean_S012D_SSIM = self.count_mean_S012D_SSIM.Top10p
            # self.TOP50p_mean_S012D_SSIM = self.count_mean_S012D_SSIM.Top50p
            # self.TOP100p_mean_S012D_SSIM = self.count_mean_S012D_SSIM.avg
            res["TOP10p_mean_SSIM_S1"] = self.count_mean_SSIM_S1.Top10p
            res["TOP50p_mean_SSIM_S1"] = self.count_mean_SSIM_S1.Top50p
            res["TOP100p_mean_SSIM_S1"] = self.count_mean_SSIM_S1.avg
            
            res["TOP10p_mean_SSIM_S2"] = self.count_mean_SSIM_S2.Top10p
            res["TOP50p_mean_SSIM_S2"] = self.count_mean_SSIM_S2.Top50p
            res["TOP100p_mean_SSIM_S2"] = self.count_mean_SSIM_S2.avg
            
            res["TOP10p_mean_SSIM_SD"] = self.count_mean_SSIM_SD.Top10p
            res["TOP50p_mean_SSIM_SD"] = self.count_mean_SSIM_SD.Top50p
            res["TOP100p_mean_SSIM_SD"] = self.count_mean_SSIM_SD.avg
            # self.count_mean_S012D_SSIM.reset()
            
            self.count_mean_PSNR_S1.reset()
            self.count_mean_PSNR_S2.reset()
            self.count_mean_S01_PSNR.reset()
            self.count_mean_S02_PSNR.reset()
            self.count_mean_S0D_PSNR.reset()
            
            self.count_mean_SSIM_S1.reset()
            self.count_mean_SSIM_S2.reset()
            self.count_mean_S01_SSIM.reset()
            self.count_mean_S02_SSIM.reset()
            self.count_mean_S0D_SSIM.reset()
            if self.use_inception:
                self.count_mean_FID_S1.reset()
                self.count_mean_FID_S2.reset()
                self.count_mean_FID_SD.reset()
                self.count_mean_FID_S01.reset()
                self.count_mean_FID_S02.reset()
                self.count_mean_FID_S0D.reset()
        
        if self.D_generation == "source":
            if not self.mode:  
                self.count_mean_PSNR_SD.reset()
                self.count_mean_SSIM_SD.reset()
        elif self.D_generation == "mergeS12":
            if not self.mode:
                self.count_mean_PSNR_S12D.reset()
                self.count_mean_SSIM_S12D.reset()
        if self.frequency:
            self.count_mean_F_S1.reset()
            self.count_mean_F_S01.reset()
            self.count_mean_F_S2.reset()
            self.count_mean_F_S02.reset()
            if self.D_generation == "source":
                self.count_mean_F_SD.reset()
                self.count_mean_F_S0D.reset()
            elif self.D_generation == "mergeS12":
                self.count_mean_F_S12D.reset()
                
        return res


def draw_Fea(data_RS0,data_RS1,data_FS1,name,outpath):
    
    # cats = np.array(self.cats)
    # cats[np.where(np.array(self.cats)<=4)] =0
    # cats[np.where(np.array(self.cats)==5)] =1
    # self.cats[np.where(np.array(self.cats)==6)] =2
    # plt.scatter(x,y,c=color[self.cat])
    import matplotlib.pyplot as plt
    plt.cla()
    plt.scatter(data_RS0[:,-1],data_RS0[:,-2],0.5,c='u',label='Features of Geniune visible Domain')
    plt.scatter(data_RS1[:,-1],data_RS1[:,-2],0.5,c='r',label='Features of Geniune polarized Domain')
    plt.scatter(data_FS1[:,-1],data_FS1[:,-2],0.5,c='b',label='Features of fake polarized Domain')
    plt.legend(loc='lower right')
    # plt.title('Feature disturbution on '+str(np.argsort(var)[-1])+' and '+str(np.argsort(var)[-2])+' dimension')
    # plt.xlabel('The '+str(np.argsort(var)[-1])+'th dimension feature')
    # plt.ylabel('The '+str(np.argsort(var)[-2])+'th dimension feature')
    plt.title('Feature disturbution on the last 2 dimension of '+name+' Modality')
    plt.xlabel('The last onedimension feature')
    plt.ylabel('The last second dimension feature')
    plt.savefig(outpath)